# 将豆瓣读书网站上的所有图书信息爬取下来，并存储到MySQL数据库中。
# 爬取信息字段要求：[ID号、书名、作者、出版社、原作名、译者、出版年、页数、定价、装帧、丛书、ISBN、评分、评论人数]
# 步骤2：根据Redis数据库的所有豆瓣图书标签爬取豆瓣读书网站上的图书列表页，获取所有图书详情页URL信息并存储到Redis数据库
# 第十一周作业
# 班级：Python五期
# 学员：李子坚

# -*- coding: utf-8 -*-
import scrapy
from booklist.items import BooklistItem
from scrapy import Request
from urllib.parse import quote
import redis,re,time,random 

class BookurlSpider(scrapy.Spider):
    '''爬取豆瓣读书网站上所有图书详情页URL的爬虫类'''
    name = 'bookurl'
    allowed_domains = ['book.douban.com']
    #start_urls = ['https://book.douban.com']
    base_url = 'https://book.douban.com'

    def start_requests(self):
        '''从Redis数据库中读取图书标签信息'''
        r = redis.Redis(host=self.settings.get("REDIS_HOST"), port=self.settings.get("REDIS_PORT"), db=self.settings.get("REDIS_DB"), decode_responses=True)
        while r.llen("book:tag_urls"):
            tag = r.lpop("book:tag_urls")
            url = self.base_url + quote(tag)
            yield Request(url=url, callback=self.parse, dont_filter=True)

    def parse(self, response):
        '''解析每个图书列表页的图书详情页URL信息'''
        #如果爬取不成功，重新发起请求
        if response.status != 200:
            yield scrapy.Request(url=response.url, callback=self.parse, dont_filter=True)

        #获取图书详情页URL列表
        book_lists = response.css('ul.subject-list > li.subject-item > div.info > h2 > a::attr(href)').extract()
        if book_lists:
            for book_url in book_lists:
                item = BooklistItem()
                item['url'] = book_url
                yield item

        #获取图书列表页下一页URL
        next_page = response.css("span.next > a::attr(href)").extract_first()
        #判断若不是最后一页
        if next_page:
            #构造下一页图书列表页的爬取
            #next_url = self.base_url + quote(next_page)
            next_url = response.urljoin(next_page)
            yield scrapy.Request(url=next_url, callback=self.parse, dont_filter=True)